#include <QGLWidget>
#include "ModelRenderer.h"
#include "Model.h"

ModelRenderer::ModelRenderer(){
    this->_model = NULL;
    this->_shader = NULL;
    this->_widget = NULL;
    this->_isSetup = false;
    this->_isInit = false;
    
    /// Typically render modes are exclusive
    this->_modes = new QActionGroup(NULL);
    this->_modes->setExclusive(true);
    
    /// Default renderer simply shows bounding box
    this->_modes->addAction( _mode_bbox = new QAction(QIcon(":/images/bbox.png"), "&Bounding Box", _modes) );
}

void ModelRenderer::setup(Model *model, QGLWidget *widget, QAction *shader){            
    this->_model  = model;
    this->_widget = widget;
    this->_shader = shader;
    this->_isSetup = true;
    
    /// Auto-Enable all defined Rendermodes
    foreach(QAction* a, renderModes()->actions()) 
        a->setCheckable(true);   
    
    /// Auto-Connect Rendermode Actions
    connect(renderModes(), SIGNAL(triggered(QAction*)), widget, SLOT(repaint()));
}

bool ModelRenderer::setRenderMode(QString name){
    bool found = false;
    foreach(QAction* mode, _modes->actions()){
        /// Remove the & characters used for shortcuts
        if(mode->text().remove("&") == name){
            found = true;
            mode->trigger();
            break;
        }
    }
    return found;
}

/// This just renders a bounding box colored with the mesh color
void ModelRenderer::render(){
    Q_ASSERT(isSetup());
    if(renderModes()->checkedAction()!=_mode_bbox) return;
    
    /// Setup BBOX color
    widget()->qglColor(model()->color);

    QBox3D bbox = model()->getBoundingBox();
    
    float min[3]; 
    min[0] = bbox.minimum().x();
    min[1] = bbox.minimum().y();
    min[2] = bbox.minimum().z();

    float max[3]; 
    max[0] = bbox.maximum().x();
    max[1] = bbox.maximum().y();
    max[2] = bbox.maximum().z();
        
    /// --- Inherited from VCG ---
    glPushAttrib(GL_ENABLE_BIT);
    glDisable(GL_LIGHTING);
    glBegin(GL_LINE_STRIP);
    glVertex3f((float)min[0],(float)min[1],(float)min[2]);
    glVertex3f((float)max[0],(float)min[1],(float)min[2]);
    glVertex3f((float)max[0],(float)max[1],(float)min[2]);
    glVertex3f((float)min[0],(float)max[1],(float)min[2]);
    glVertex3f((float)min[0],(float)min[1],(float)min[2]);
    glEnd();
    glBegin(GL_LINE_STRIP);
    glVertex3f((float)min[0],(float)min[1],(float)max[2]);
    glVertex3f((float)max[0],(float)min[1],(float)max[2]);
    glVertex3f((float)max[0],(float)max[1],(float)max[2]);
    glVertex3f((float)min[0],(float)max[1],(float)max[2]);
    glVertex3f((float)min[0],(float)min[1],(float)max[2]);
    glEnd();
    glBegin(GL_LINES);
    glVertex3f((float)min[0],(float)min[1],(float)min[2]);
    glVertex3f((float)min[0],(float)min[1],(float)max[2]);
    glVertex3f((float)max[0],(float)min[1],(float)min[2]);
    glVertex3f((float)max[0],(float)min[1],(float)max[2]);
    glVertex3f((float)max[0],(float)max[1],(float)min[2]);
    glVertex3f((float)max[0],(float)max[1],(float)max[2]);
    glVertex3f((float)min[0],(float)max[1],(float)min[2]);
    glVertex3f((float)min[0],(float)max[1],(float)max[2]);
    glEnd();
    glPopAttrib();        
}
